// Filename: fontclass.cpp

#include "fontclass.h"

//-------------------------------------------------------------------------------------------------------------------
FontClass::FontClass() : m_Font(0), m_Texture(0)
{ }

//-------------------------------------------------------------------------------------------------------------------
FontClass::FontClass(const FontClass& rhs)
{ }

//-------------------------------------------------------------------------------------------------------------------
FontClass::~FontClass()
{ }

//-------------------------------------------------------------------------------------------------------------------
bool FontClass::Initialize(ID3D11Device* device, char* fontFilename, WCHAR* textureFilename)
{
	bool result;

	result = LoadFontData(fontFilename);	// Load in the text file containing the font data.
	if (!result) return false;
	
	result = LoadTexture(device, textureFilename);	// Load the font texture.
	if (!result) return false;

	return true;
}

//-------------------------------------------------------------------------------------------------------------------
void FontClass::Shutdown()
{
	ReleaseTexture();		// Release the font texture.
	ReleaseFontData();		// Release the font data.
}

//-------------------------------------------------------------------------------------------------------------------
bool FontClass::LoadFontData(char* filename)
{
	ifstream	fin;		// File input stream used to read indexing data in fontdata.txt.
	int			i;			// Index variable used in for loop.
	char		temp;		// Buffer to store unneeded characters in fontdata.txt.

	// Create the font spacing buffer.
	m_Font = new FontType[95];
	if (!m_Font)
		return false;

	// Read in the font size and spacing between chars.
	fin.open(filename);
	if (fin.fail())
		return false;

	// Read in the 95 used ascii characters for text.
	for (i=0; i<95; ++i)
	{
		fin.get(temp);
		while (temp != ' ')
		{
			fin.get(temp);
		}
		fin.get(temp);
		while(temp != ' ')
		{
			fin.get(temp);	// Get to first TU coordinate.
		}

		fin >> m_Font[i].left;
		fin >> m_Font[i].right;
		fin >> m_Font[i].size;
	}

	// Close the file.
	fin.close();

	return true;
}

//-------------------------------------------------------------------------------------------------------------------
void FontClass::ReleaseFontData()
{
	if (m_Font)	 // Release the font data array.
	{
		delete [] m_Font;
		m_Font = nullptr;
	}
}

//-------------------------------------------------------------------------------------------------------------------
bool FontClass::LoadTexture(ID3D11Device* device, WCHAR* filename)
{
	bool result;

	m_Texture = new TextureClass;	// Create the texture object.
	if (!m_Texture) return false;
	
	result = m_Texture->Initialize(device, filename);	// Initialize the texture object.
	if (!result) return false;

	return true;
}

//-------------------------------------------------------------------------------------------------------------------
void FontClass::ReleaseTexture()
{
	if (m_Texture)	// Release the texture object.
	{
		m_Texture->Shutdown();
		delete m_Texture;
		m_Texture = nullptr;
	}
}

//-------------------------------------------------------------------------------------------------------------------
ID3D11ShaderResourceView* FontClass::GetTexture()
{
	return m_Texture->GetTexture();
}


//-------------------------------------------------------------------------------------------------------------------
void FontClass::BuildVertexArray(void* vertices, char* sentenceText, float drawX, float drawY)
{
	VertexType*		vertexPtr;
	int				numLetters, index, i, letter;
	
	vertexPtr = (VertexType*)vertices;			// Coerce the input vertices into a VertexType structure.
	numLetters = (int)strlen(sentenceText);		// Get the number of letters in the sentance.
	index = 0;									// Initialize the index to the vertex array.

	// Draw each letter onto a quad.
	for (i=0; i<numLetters; i++)
	{
		letter = ((int)sentenceText[i]) - 32;	// Get letter index for FontType array.

		// If the letter is a space then just move over three pixels.
		if (letter == 0)
		{
			drawX = drawX + 3.0f;
		}
		else
		{
			// First triangle in quad.
			vertexPtr[index].position = D3DXVECTOR3(drawX, drawY, 0.0f);		// Top left.
			vertexPtr[index].texture  = D3DXVECTOR2(m_Font[letter].left, 0.0f);
			++index;

			vertexPtr[index].position = D3DXVECTOR3((drawX + m_Font[letter].size), (drawY - 16), 0.0f);	// Bottom right.
			vertexPtr[index].texture  = D3DXVECTOR2(m_Font[letter].right, 1.0f);
			++index;

			vertexPtr[index].position = D3DXVECTOR3(drawX, (drawY - 16), 0.0f);	// Bottom left.
			vertexPtr[index].texture  = D3DXVECTOR2(m_Font[letter].left, 1.0f);
			++index;

			// Second triangle in quad.
			vertexPtr[index].position = D3DXVECTOR3(drawX, drawY, 0.0f);	// Top left.
			vertexPtr[index].texture  = D3DXVECTOR2(m_Font[letter].left, 0.0f);
			++index;

			vertexPtr[index].position = D3DXVECTOR3(drawX + m_Font[letter].size, drawY, 0.0f);  // Top right.
			vertexPtr[index].texture  = D3DXVECTOR2(m_Font[letter].right, 0.0f);
			index++;

			vertexPtr[index].position = D3DXVECTOR3((drawX + m_Font[letter].size), (drawY - 16), 0.0f);  // Bottom right.
			vertexPtr[index].texture  = D3DXVECTOR2(m_Font[letter].right, 1.0f);
			index++;

			// Update the x location for drawing by the size of the letter and one pixel.
			drawX = drawX + m_Font[letter].size + 1.0f;
		}
	}
}